
import _ from 'lodash'
import Vue from 'vue'
/**
     * @function to map the parameters of the stream function/window
     * @param streamHandler { // type: 'window'
            // value: {
            //     function: 'batch',
            //     parameters: ['1']
            // }
     * @param div ''
     * @param onChange to check if the method is called on change of the drop-down or on load of the form
     */

export const mapParameterValues = function (streamHandler, predefinedFunctions2, onChange = false) {
    const newstreamHandler = _.cloneDeep(streamHandler)
    var predefinedFunctions;
    var functionName = "";
    var parameters;
    var savedType = newstreamHandler.function.toLowerCase();// 'batch'
    var savedParameters = newstreamHandler.parameters; // '[1]'
    // var windowFunctionType = newstreamHandler.type.toLowerCase()//'window';
    var parameterLength = { sameLength: 0 };
    // if (windowFunctionType === Constants.WINDOW) {
    predefinedFunctions = _.cloneDeep(predefinedFunctions2)
    // }
    // else {
    //   predefinedFunctions = _.orderBy(_.cloneDeep
    //     (self.configurationData.rawExtensions["streamFunctions"]), ['name'], ['asc']);
    // }
    var functionParameters = getSelectedTypeParameters(savedType, predefinedFunctions);

    // functionName = getFunctionNameWithParameterOverloads(predefinedFunctions, savedType,
    //     savedParameters, parameterLength)
    functionName = getFunctionNameWithParameterOverloads(predefinedFunctions, savedType,
        savedParameters, parameterLength)
    var overloadParameters = getParameterOverloads(functionName, functionParameters);
    // parameters = createObjectsForUnknownParameters(functionParameters, savedParameters);
    // if (parameterLength.sameLength > 1 && !onChange) {
    //     parameters = createObjectsForUnknownParameters(functionParameters, savedParameters);
    //     //renderUnknownParameters(parameters, functionParameters, windowFunctionType, div);
    // } else {
    parameters = createObjectsForKnownParameters(overloadParameters, savedParameters);
    //     //renderParameters(parameters, windowFunctionType, div);
    // }
    return {
        functionName,
        parameters
    }
};
const createObjectsForKnownParameters = function (predefinedParameters, savedParameters) {
    var parameters = [];
    var lengthOfSavedParameters = savedParameters.length;
    var savedParamIndex = 0;
    for (var i = 0; i < predefinedParameters.length; i++) {
        if (i < lengthOfSavedParameters) {
            var savedValue = savedParameters[savedParamIndex];
            if (predefinedParameters[i].isMultiValue) {
                var parameterValue = [];
                for (var j = i; j < savedParameters.length; j++) {
                    //                     defaultValue: "asc"
                    // description: "The order define as \"asc\" or \"desc\"."
                    // isMultiValue: false
                    // name: "order"
                    // optional: true
                    // value: "'desc'"
                    parameterValue.push({
                        value: savedParameters[j],
                        name: "",
                        defaultValue: ""
                    });
                }
                savedValue = parameterValue;
                lengthOfSavedParameters = lengthOfSavedParameters - (parameterValue.length - 1);
                savedParamIndex = savedParamIndex + (parameterValue.length - 1);
            }
            parameters.push({
                name: predefinedParameters[i].name, value: savedValue, description:
                    predefinedParameters[i].description, optional: predefinedParameters[i].optional,
                defaultValue: predefinedParameters[i].defaultValue,
                isMultiValue: predefinedParameters[i].isMultiValue
            });
        } else {
            var value;
            if (predefinedParameters[i].isMultiValue) {
                value = [{
                    value: "",
                    name: "",
                    defaultValue: ""
                }];
            } else {
                value = ""
            }
            parameters.push({
                name: predefinedParameters[i].name, value: value, description: predefinedParameters[i]
                    .description, optional: predefinedParameters[i].optional,
                defaultValue: predefinedParameters[i].defaultValue,
                isMultiValue: predefinedParameters[i].isMultiValue
            });
        }
        savedParamIndex++;
    }
    return parameters;
};
const createObjectsForUnknownParameters = function (predefinedParameters, savedParameters) {
    var parameters = [];
    var lengthOfSavedParameters = savedParameters.length;
    var savedParamIndex = 0;
    for (var i = 0; i < predefinedParameters.length; i++) {
        var name = "Parameter " + (i + 1);
        if (i < lengthOfSavedParameters) {
            var savedValue = savedParameters[savedParamIndex];
            if (predefinedParameters[i].isMultiValue) {
                var parameterValue = [];
                for (var j = i; j < savedParameters.length; j++) {
                    parameterValue.push(savedParameters[j]);
                }
                savedValue = parameterValue;
                lengthOfSavedParameters = lengthOfSavedParameters - (parameterValue.length - 1);
                savedParamIndex = savedParamIndex + (parameterValue.length - 1);
            }
            parameters.push({
                name: name, value: savedValue, optional: predefinedParameters[i].optional,
                isMultiValue: predefinedParameters[i].isMultiValue
            });
        } else {
            var value;
            if (predefinedParameters[i].isMultiValue) {
                value = [""];
            } else {
                value = ""
            }
            parameters.push({
                name: name, value: value, optional: predefinedParameters[i].optional,
                isMultiValue: predefinedParameters[i].isMultiValue
            });
        }
        savedParamIndex++;
    }
    return parameters;
};

const getSelectedTypeParameters = function (selectedType, predefinedTypes) {
    var self = this;
    var parameters = [];
    selectedType = getFunctionNameWithoutParameterOverload(selectedType);
    _.forEach(predefinedTypes, function (type) {
        if (type.name.toLowerCase() == selectedType.toLowerCase()) {
            if (type.parameters) {
                parameters = type.parameters;
            }
            return false;
        }
    });
    return parameters;
};
const getFunctionNameWithoutParameterOverload = function (functionName) {
    if (functionName.includes("(")) {
        return functionName.split("(")[0].trim();
    }
    return functionName;
}
const getParameterOverloads = function (functionName, predefinedParameters) {
    var parameterOverloads = [];
    var multiValue;
    if (functionName.includes("(")) {
        var regexToGetTextInsideBrackets = /\(([^)]+)\)/;
        var overloads = regexToGetTextInsideBrackets.exec(functionName)[1].trim();
        var listOfOverloads = overloads.split(",");
        _.forEach(listOfOverloads, function (overload, index) {
            multiValue = false;
            overload = overload.trim();
            _.forEach(predefinedParameters, function (parameter) {
                var constants = {
                    FILE: 'file',
                    CRON_EXPRESSION: ' cron.expression '
                };
                if (listOfOverloads[index + 1] == '...') {
                    multiValue = true;
                }
                if (overload === parameter.name) {
                    parameterOverloads.push({
                        name: parameter.name, description: parameter.description,
                        optional: parameter.optional, defaultValue: parameter.defaultValue,
                        isMultiValue: multiValue
                    });
                    return false;
                }
            });
        });
    } else {
        parameterOverloads = predefinedParameters;
    }
    return parameterOverloads;
};
const getFunctionNameWithParameterOverloads = function (predefinedFunctions, savedType,
    savedParameters, sameParameterLengths) {
    var functionName = "";
    _.forEach(predefinedFunctions, function (predefinedFunction) {
        if (predefinedFunction.name.toLowerCase() === savedType) {
            if (predefinedFunction.parameterOverloads) {
                var nameWithUniqueOverload = predefinedFunction.name + "(";
                var overload;
                for (var i = 0; i < predefinedFunction.parameterOverloads.length; i++) {
                    overload = predefinedFunction.parameterOverloads[i];
                    var lengthOfSavedParameters = savedParameters.length;
                    var noOfOverloadParameters = overload.length;
                    for (var k = 0; k < overload.length; k++) {
                        if (overload[k + 1] == '...') {
                            var multiValues = [];
                            for (var j = k; j < savedParameters.length; j++) {
                                multiValues.push(savedParameters[j])
                            }
                            lengthOfSavedParameters = lengthOfSavedParameters - (multiValues.length - 1);
                            noOfOverloadParameters = noOfOverloadParameters - 1;
                        }
                    }
                    if (noOfOverloadParameters === lengthOfSavedParameters) {
                        sameParameterLengths.sameLength = sameParameterLengths.sameLength + 1;
                        // nameWithUniqueOverload += overload;
                    }
                }
                nameWithUniqueOverload += overload + ")";
                functionName = nameWithUniqueOverload;
            } else {
                var nameWithAllParameters = predefinedFunction.name + "(";
                _.forEach(predefinedFunction.parameters, function (parameter) {
                    nameWithAllParameters += parameter.name + ",";
                });
                if (predefinedFunction.parameters && predefinedFunction.parameters.length !== 0) {
                    nameWithAllParameters = nameWithAllParameters.slice(0, -1);
                }
                nameWithAllParameters += ")";
                functionName = nameWithAllParameters
            }
        }
    });
    return functionName;
};

export const flattenOperators = function (meta) {
    // Flatten in-built operators.
    var operators = [];
    var type;
    for (type in meta.inBuilt) {
        if (meta.inBuilt.hasOwnProperty(type)) {
            meta.inBuilt[type].forEach(function (operator) {
                var cloneOperator = _.clone(operator);
                cloneOperator.fqn = cloneOperator.name;
                cloneOperator.type = type;
                operators.push(cloneOperator);
            });
        }
    }
    operators.sort(function (a, b) {
        return a.fqn < b.fqn ? -1 : a.fqn > b.fqn ? 1 : 0;
    });

    // Flatten extensions.
    var extensions = [];
    for (var extension in meta.extensions) {
        if (meta.extensions.hasOwnProperty(extension)) {
            for (type in meta.extensions[extension]) {
                if (meta.extensions[extension].hasOwnProperty(type)) {
                    meta.extensions[extension][type].forEach(function (operator) {
                        var cloneOperator = _.clone(operator);
                        cloneOperator.fqn = cloneOperator.namespace + ':' + cloneOperator.name;
                        cloneOperator.type = type;
                        extensions.push(cloneOperator);
                    });
                }
            }
        }
    }
    extensions.sort(function (a, b) {
        return a.fqn < b.fqn ? -1 : a.fqn > b.fqn ? 1 : 0;
    });
    return operators.concat(extensions);
}
export function obtainStreamFunctionsFromResponse(extensions) {
    let response = _.cloneDeep(extensions)
    var snippets = {};
    var processorTypes = Object.keys(response.inBuilt);
    var processorTypeCount = 0;
    for (var processorType in response.inBuilt) {
        if (response.inBuilt.hasOwnProperty(processorType)) {
            var snippet = {};
            for (var i = 0; i < response.inBuilt[processorType].length; i++) {
                var parameterOverloads = response.inBuilt[processorType][i].parameterOverloads;
                if (parameterOverloads === undefined || parameterOverloads.length === 0) {
                    snippet[response.inBuilt[processorType][i].name] =
                        generateSnippetFromProcessorMetaData(response.
                            inBuilt[processorType][i], processorTypes[processorTypeCount]);
                }
                else {
                    for (var j = 0; j < parameterOverloads.length; j++) {
                        var overloadParamArray = parameterOverloads[j];
                        var overloadParamAsString =
                            generateSnippetFromProcessorName(overloadParamArray);
                        var updatedProcessorName = response.inBuilt[processorType][i].name +
                            overloadParamAsString;
                        snippet[updatedProcessorName] =
                            generateSnippetFromProcessorMetaDataForParamOverloads(response.
                                inBuilt[processorType][i], updatedProcessorName,
                                overloadParamArray, processorTypes[processorTypeCount]);
                    }
                }
            }
            snippets[processorType] = snippet;
        }
        processorTypeCount++;
    }
    const functObj = {
        functionOperationSnippets: snippets
    }
    return ceshi233(functObj, response)

}
function generateSnippetFromProcessorName(overloadParamArray) {
    var overloadParamAsString = "";
    if (overloadParamArray !== undefined) {
        for (var k = 0; k < overloadParamArray.length; k++) {
            if (k === 0) {
                overloadParamAsString += "(";
                overloadParamAsString += overloadParamArray[k];
            } else {
                overloadParamAsString += ", " + overloadParamArray[k];
            }

            if (k === overloadParamArray.length - 1) {
                overloadParamAsString += ")"
            }
        }
    }

    return overloadParamAsString;
}
function generateSnippetFromProcessorMetaDataForParamOverloads(processorMetaData, processorName,
    parameterOverloads, processorTypeName) {
    var snippetVariableCount = 0;
    var snippetText = "snippet " + processorName + "\n\t" + processorMetaData.name;
    if (parameterOverloads) {
        snippetText += "(";
        for (var i = 0; i < parameterOverloads.length; i++) {
            var parameter = parameterOverloads[i];
            if (i !== 0) {
                snippetText += ", ";
            }
            snippetText += "${" + (snippetVariableCount + 1) + ":" + parameter + "}";
            snippetVariableCount++;
        }
        snippetText += ")\n";
    }
    var snippet = parseSnippetFile(snippetText)[0];

    if (processorMetaData.description || processorMetaData.returnType || processorMetaData.parameters) {
        // snippet.description = utils.generateDescriptionForProcessor(processorMetaData, processorTypeName,
        //     processorName, parameterOverloads);
    }
    return snippet;
}
function generateSnippetFromProcessorMetaData(processorMetaData, processorTypeName) {
    var snippetVariableCount = 0;
    var snippetText = "snippet " + processorMetaData.name + "\n\t" + processorMetaData.name;
    if (processorMetaData.parameters) {
        snippetText += "(";
        for (var i = 0; i < processorMetaData.parameters.length; i++) {
            var parameter = processorMetaData.parameters[i];
            if (i !== 0) {
                snippetText += ", ";
            }
            snippetText += "${" + (snippetVariableCount + 1) + ":" + parameter.name + "}";
            snippetVariableCount++;
        }
        snippetText += ")\n";
    }
    var snippet = parseSnippetFile(snippetText)[0];

    if (processorMetaData.description || processorMetaData.returnType || processorMetaData.parameters) {
        // snippet.description = utils.generateDescriptionForProcessor(processorMetaData, processorTypeName,
        //     undefined, undefined);
    }
    return snippet;
}
function parseSnippetFile(str) {
    str = str.replace(/\r/g, "");
    var list = [], snippet = {};
    var re = /^#.*|^({[\s\S]*})\s*$|^(\S+) (.*)$|^((?:\n*\t.*)+)/gm;
    var m;
    while (m = re.exec(str)) {
        if (m[1]) {
            try {
                snippet = JSON.parse(m[1]);
                list.push(snippet);
            } catch (e) {
            }
        }
        if (m[4]) {
            snippet.content = m[4].replace(/^\t/gm, "");
            list.push(snippet);
            snippet = {};
        } else {
            var key = m[2], val = m[3];
            if (key == "regex") {
                var guardRe = /\/((?:[^\/\\]|\\.)*)|$/g;
                snippet.guard = guardRe.exec(val)[1];
                snippet.trigger = guardRe.exec(val)[1];
                snippet.endTrigger = guardRe.exec(val)[1];
                snippet.endGuard = guardRe.exec(val)[1];
            } else if (key == "snippet") {
                snippet.tabTrigger = val.match(/^\S*/)[0];
                if (!snippet.name)
                    snippet.name = val;
            } else {
                snippet[key] = val;
            }
        }
    }
    return list;
};
export function ceshi233(obj, obj2) {
    let rawExtensions = _.cloneDeep(obj)
    let response = _.cloneDeep(obj2)
    var snippets = {};
    var streamFunctions = [];
    var functions = [];
    rawExtensions.store = response.extensions["store"]["stores"];
    rawExtensions.sink = response.extensions["sink"]["sinks"];
    rawExtensions.source = response.extensions["source"]["sources"];
    rawExtensions.sourceMaps = response
        .extensions["sourceMapper"]["sourceMaps"];
    rawExtensions.sinkMaps = response.extensions["sinkMapper"]["sinkMaps"];
    rawExtensions.windowFunctionNames = response.inBuilt["windowProcessors"];
    rawExtensions.incrementalAggregators = response.extensions
    ["incrementalAggregator"]["functions"];
    obtainStreamFunctionsFromResponse1(response.extensions, streamFunctions);
    obtainStreamFunctionsFromResponse1(response.inBuilt, streamFunctions);
    obtainFunctionFromResponse(response.extensions, functions,
        rawExtensions.incrementalAggregators);
    obtainFunctionFromResponse(response.inBuilt, functions,
        rawExtensions.incrementalAggregators);
    rawExtensions.streamFunctions = streamFunctions;
    rawExtensions.functions = functions;
    for (var namespace in response.extensions) {
        if (response.extensions.hasOwnProperty(namespace)) {
            var processors = {};
            var processorTypes = Object.keys(response.extensions[namespace]);
            var processorTypeCount = 0;
            for (var processorType in response.extensions[namespace]) {
                if (response.extensions[namespace].hasOwnProperty(processorType)) {
                    var snippet = {};
                    for (var i = 0; i < response.extensions[namespace][processorType].length;
                        i++) {
                        var parameterOverloads = response.extensions[namespace]
                        [processorType][i].parameterOverloads;
                        if (parameterOverloads === undefined ||
                            parameterOverloads.length === 0) {
                            snippet[response.extensions[namespace][processorType][i].name] =
                                generateSnippetFromProcessorMetaData(response.
                                    extensions[namespace][processorType][i],
                                    processorTypes[processorTypeCount]);
                        }
                        else {
                            for (var j = 0; j < parameterOverloads.length; j++) {
                                var overloadParamArray = parameterOverloads[j];
                                var overloadParamAsString =
                                    generateSnippetFromProcessorName(overloadParamArray);
                                var updatedProcessorName = response.extensions
                                [namespace][processorType][i].name +
                                    overloadParamAsString;
                                snippet[updatedProcessorName] =
                                    generateSnippetFromProcessorMetaDataForParamOverloads
                                        (response.extensions[namespace][processorType][i],
                                            updatedProcessorName, overloadParamArray,
                                            processorTypes[processorTypeCount]);
                            }
                        }
                    }
                    if (Object.keys(snippet).length > 0) {
                        processors[processorType] = snippet;
                    }
                }
                processorTypeCount++;
            }
            if (Object.keys(processors).length > 0) {
                snippets[namespace] = processors;
            }
        }
    }
    // CompletionEngine.functionOperationSnippets.extensions = snippets
    return rawExtensions;
}
function obtainStreamFunctionsFromResponse1(extensions, streamFunctions) {
    _.forEach(extensions, function (extension) {
        _.forEach(extension.streamProcessors, function (streamFunction) {
            var parameterOverloads;
            if (streamFunction.parameterOverloads) {
                parameterOverloads = streamFunction.parameterOverloads;
            }
            var streamProcessorFunction = {
                description: streamFunction.description,
                examples: streamFunction.examples,
                name: streamFunction.namespace + ':' + streamFunction.name,
                parameters: streamFunction.parameters,
                parameterOverloads: parameterOverloads,
                returnAttributes: streamFunction.returnAttributes
            }
            streamFunctions.push(streamProcessorFunction);
        });
    });
}
function obtainFunctionFromResponse(extensions, functions, aggregateFunctions) {
    _.forEach(extensions, function (extension) {
        _.forEach(extension.functions, function (normalFunction) {
            if (!_.some(aggregateFunctions, normalFunction)) {
                var parameterOverloads;
                if (normalFunction.parameterOverloads) {
                    parameterOverloads = normalFunction.parameterOverloads;
                }
                var functionObject = {
                    description: normalFunction.description,
                    examples: normalFunction.examples,
                    name: normalFunction.namespace + ':' + normalFunction.name,
                    parameters: normalFunction.parameters,
                    parameterOverloads: parameterOverloads,
                    returnAttributes: normalFunction.returnAttributes
                };
                functions.push(functionObject);
            }
        });
    });
}
export function setFlow(data) {
    const newData = _.cloneDeep(data);
    let isMultiValues = [];
    let arr = newData.map((v) => {
        // 判断是否是多值
        if (v.isMultiValue) {
            isMultiValues = v.value.map((e) => {
                if (!e.value) {
                    Vue.prototype.$msg(v.name + "不能为空");
                    throw new Error(v.name + "不能为空");
                }
                return e.value;
            });
        } else {
            isMultiValues = [];
            if (!v.value) {
                Vue.prototype.$msg(v.name + "不能为空");
                throw new Error(v.name + "不能为空");
            }
            return v.value;
        }
    });
    const a = arr.concat(isMultiValues).filter((v) => v);
    console.log(a, '???咋回事')
    return a
}